package com.hoelg.hgc;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.hoelg.hgc.DAO.Desc;
import com.hoelg.hgc.DAO.HGCUser;
import com.hoelg.hgc.constants.Utils;
import com.hoelg.hgc.webservices.AddCat;
import com.hoelg.hgc.webservices.AddDesc;
import com.hoelg.hgc.webservices.LnC;
import com.hoelg.hgc.webservices.RecupCats;
import com.hoelg.hgc.webservices.RecupDesc;

public class MainActivity extends Activity implements OnClickListener {

	public Refresh task;
	public GetCats taskGetCats;
	public DescAdding taskDescAdding;
	public CatAdding taskCatAdding;
	public GetDescs taskGetDescs;
	
	public String[] categories;
	
	public Desc desc1, desc2, desc3;
	
	public List<Desc> descriptions;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		initialyseUI();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.addCat:
			addCat();
			break;
		case R.id.addDesc:
			addDesc();
			break;
		}
		return true;
	}

	private void addCat(){ 
		final DialogCat dialog = new DialogCat(this);
		dialog.setContentView(R.layout.dialog_addcat);
		dialog.setTitle(R.string.addCat);
		Button srv = (Button) dialog.findViewById(R.id.btValid);
		srv.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				ToggleButton typeCat = (ToggleButton) dialog.findViewById(R.id.catKind);
				String catKind;
				if (typeCat.isChecked()) 
					catKind = "I";
				else 
					catKind = "O";
				EditText catName = (EditText) dialog.findViewById(R.id.catName);
				String sCatName = catName.getText().toString();
				taskCatAdding = new CatAdding();
				taskCatAdding.execute(sCatName, catKind, dialog);
			}
		});
		
		dialog.show();
	}
	
	private void addDesc(){ 
		final DialogDesc dialog = new DialogDesc(this);
		dialog.setContentView(R.layout.dialog_adddesc);
		dialog.setTitle(R.string.addDesc);
		
		Spinner catsSpinner = (Spinner) dialog.findViewById(R.id.spinnerCat);
		ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(MainActivity.this, android.R.layout.simple_spinner_item,
		       categories);
		// Specify the layout to use when the list of choices appears
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		// Apply the adapter to the spinner
		catsSpinner.setAdapter(adapter);
		
		Button validDesc = (Button) dialog.findViewById(R.id.btValid);
		validDesc.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Spinner cat = (Spinner) dialog.findViewById(R.id.spinnerCat);
				String catName = (String) cat.getSelectedItem();
				catName =  catName.replaceFirst("Recette - ", "");
				catName = catName.replaceFirst("Dépense - ", "");
				EditText descName = (EditText) dialog.findViewById(R.id.descName);
				String sDescName = descName.getText().toString();
				taskDescAdding = new DescAdding();
				taskDescAdding.execute(catName, sDescName, dialog);
			}
		});
		dialog.show();
	}

	//classe interne de gestion des taches de fond de la connexion
	public class GetCats extends AsyncTask<Void, Void, Void> {

		private String[] cats;
		
		private boolean allOk = false;
		
		@Override
		protected void onPreExecute() {
			//gestion de l'attente
			showDialog(1);
		}

		@Override
		protected void onPostExecute(final Void unused) {
			removeDialog(1);
			//connect();
			if (allOk){
				MainActivity.this.categories = cats;
			}
			else{
				Toast toast = Toast.makeText(getApplicationContext(), "Problème de chargement des catégories", Toast.LENGTH_SHORT);
				toast.show();
				return;
			}
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {
				RecupCats ws = new RecupCats();

				ws.executeWebService();

				if (!Utils.isNullOrEmpty(ws.getResultatWS()) && ws.getResultatWS().equals("OK")) {
					allOk = true;
				}
				cats = (String[])ws.getRawResult();

			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// TODO Auto-generated method stub
			return null;
		}

	}
	//classe interne de gestion des taches de fond de la connexion
	public class GetDescs extends AsyncTask<Void, Void, Void> {

		private List<Desc> descs;
		
		private boolean allOk = false;
		
		@Override
		protected void onPreExecute() {
			//gestion de l'attente
			showDialog(3);
		}

		@Override
		protected void onPostExecute(final Void unused) {
			removeDialog(3);
			//connect();
			if (allOk){
				MainActivity.this.descriptions = descs;
			}
			else{
				Toast toast = Toast.makeText(getApplicationContext(), "Problème de chargement des descriptions", Toast.LENGTH_SHORT);
				toast.show();
				return;
			}
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {
				RecupDesc ws = new RecupDesc();

				ws.executeWebService();

				if (!Utils.isNullOrEmpty(ws.getResultatWS()) && ws.getResultatWS().equals("OK")) {
					allOk = true;
				}
				descs = (List<Desc>)ws.getRawResult();

			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// TODO Auto-generated method stub
			return null;
		}

	}

	//classe interne de gestion des taches de fond de la connexion
	public class CatAdding extends AsyncTask<Object, Void, Void> {

		private boolean allOk = false;

		private String cat;
		
		private String catKind;
		
		private Dialog caller;

		@Override
		protected void onPreExecute() {
			//gestion de l'attente
			showDialog(2);
		}

		@Override
		protected void onPostExecute(final Void unused) {
			removeDialog(2);
			//connect();
			if (allOk){
				((EditText) caller.findViewById(R.id.catName)).setText("");
			}
			else{
				Toast toast = Toast.makeText(getApplicationContext(), "Problème lors de l'ajout de la catégorie", Toast.LENGTH_SHORT);
				toast.show();
				return;
			}
		}

		@Override
		protected Void doInBackground(Object... params) {
			try {
				cat = (String) params[0];
				catKind = (String) params[1];
				caller = (Dialog) params[2];
				
				AddCat ws = new AddCat(cat, catKind);

				ws.executeWebService();

				if (!Utils.isNullOrEmpty(ws.getResultatWS()) && ws.getResultatWS().equals("OK")) {
					allOk = true;
				}

			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// TODO Auto-generated method stub
			return null;
		}

	}
	
	

	//classe interne de gestion des taches de fond de la connexion
	public class DescAdding extends AsyncTask<Object, Void, Void> {

		private boolean allOk = false;

		private String cat;
		
		private String desc;
		
		private Dialog caller;

		@Override
		protected void onPreExecute() {
			//gestion de l'attente
			showDialog(2);
		}

		@Override
		protected void onPostExecute(final Void unused) {
			removeDialog(2);
			//connect();
			if (allOk){
				((EditText) caller.findViewById(R.id.descName)).setText("");
			}
			else{
				Toast toast = Toast.makeText(getApplicationContext(), "Problème lors de l'ajout de la catégorie", Toast.LENGTH_SHORT);
				toast.show();
				return;
			}
		}

		@Override
		protected Void doInBackground(Object... params) {
			try {
				cat = (String) params[0];
				desc = (String) params[1];
				caller = (Dialog) params[2];
				
				AddDesc ws = new AddDesc(cat, desc);

				ws.executeWebService();

				if (!Utils.isNullOrEmpty(ws.getResultatWS()) && ws.getResultatWS().equals("OK")) {
					allOk = true;
				}

			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// TODO Auto-generated method stub
			return null;
		}

	}
	
	
	
	public void initialyseUI(){
        setContentView(R.layout.activity_main);
		Button button = (Button)findViewById(R.id.btn_refresh);
		button.setOnClickListener(this);
		Button bt1 = (Button)findViewById(R.id.btdesc1);
		bt1.setOnClickListener(this);
		Button bt2 = (Button)findViewById(R.id.btdesc2);
		bt2.setOnClickListener(this);
		Button bt3 = (Button)findViewById(R.id.btdesc3);
		bt3.setOnClickListener(this);
		TextView solde = (TextView) MainActivity.this.findViewById(R.id.tvSolde);
		solde.setText(HGCUser.getInstance().getBalance() + " €");
		refreshCats();
		refreshDescs();
	}

	public void refreshCats() {
		taskGetCats = new GetCats();
		taskGetCats.execute();
	}
	public void refreshDescs() {
		taskGetDescs = new GetDescs();
		taskGetDescs.execute();
	}

	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_refresh:
			String mntDepRec1 = ((EditText)findViewById(R.id.etdeprec1)).getText().toString();
			if (!Utils.isNullOrEmpty(mntDepRec1) && null != desc1 && desc1.getDescID() != 0) {
				task = new Refresh();
				if (desc1.isRecette()) {
					task.execute(mntDepRec1, Integer.toString(desc1.getDescID()));
				}
				else {
					task.execute("-"+mntDepRec1, Integer.toString(desc1.getDescID()));
				}
			}
			String mntDepRec2 = ((EditText)findViewById(R.id.etdeprec2)).getText().toString();
			if (!Utils.isNullOrEmpty(mntDepRec2) && null != desc2 && desc2.getDescID() != 0) {
				task = new Refresh();
				if (desc2.isRecette()) {
					task.execute(mntDepRec2, Integer.toString(desc2.getDescID()));
				}
				else {
					task.execute("-"+mntDepRec2, Integer.toString(desc2.getDescID()));
				}
			}
			String mntDepRec3 = ((EditText)findViewById(R.id.etdeprec2)).getText().toString();
			if (!Utils.isNullOrEmpty(mntDepRec3) && null != desc3 && desc3.getDescID() != 0) {
				task = new Refresh();
				if (desc3.isRecette()) {
					task.execute(mntDepRec3, Integer.toString(desc3.getDescID()));
				}
				else {
					task.execute("-"+mntDepRec3, Integer.toString(desc3.getDescID()));
				}
			}

			desc1 = null;
			desc2 = null;
			desc3 = null;
			break;
		default:
			showPopupDesc(v.getId());
			break;
		}
	}
	
	public void showPopupDesc(final int id) {
		final Dialog dialog = new Dialog(MainActivity.this);
		dialog.setContentView(R.layout.dialog_list);
		final ListView liste = (ListView) dialog.findViewById(R.id.list);
		liste.setBackgroundColor(Color.LTGRAY);
		liste.setAdapter(new EfficientAdapter(MainActivity.this, descriptions));
		liste.setOnItemClickListener(new OnItemClickListener() {
			
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				switch (id) {
				case R.id.btdesc1:
					desc1 = (Desc) liste.getAdapter().getItem(arg2);
					break;
				case R.id.btdesc2:
					desc2 = (Desc) liste.getAdapter().getItem(arg2);
					break;
				case R.id.btdesc3:
					desc3 = (Desc) liste.getAdapter().getItem(arg2);
					break;
				}
				
				dialog.cancel();	
			}
		});

		dialog.show();
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		ProgressDialog dialog = new ProgressDialog(MainActivity.this);
		dialog.setCancelable(true);
		switch (id) {
		case 0:
			dialog.setMessage("Calcul en cours...");
			break;
		case 1:
			dialog.setMessage("Récupération des catégories...");
			break;
		case 2:
			dialog.setMessage("Ajout en cours...");
			break;
		case 3:
			dialog.setMessage("Récupération des descriptions...");
			break;
		}
		// set the progress to be horizontal
		dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		return dialog;
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		initialyseUI();
		removeDialog(0);
		removeDialog(1);
		removeDialog(2);
		removeDialog(3);
	}

	//classe interne de gestion des taches de fond de la connexion
	public class Refresh extends AsyncTask<String, Void, Void> {

		private boolean allOk = false;
				
		@Override
		protected void onPreExecute() {
			//gestion de l'attente
			showDialog(0);
		}

		@Override
		protected void onPostExecute(final Void unused) {
			removeDialog(0);
			//connect();
			if (allOk){
				TextView solde = (TextView) MainActivity.this.findViewById(R.id.tvSolde);
				solde.setText(HGCUser.getInstance().getBalance() + "€");
			}
			else{
				Toast toast = Toast.makeText(getApplicationContext(), "Problème lors du calcul du solde", Toast.LENGTH_SHORT);
				toast.show();
				return;
			}
			((EditText)MainActivity.this.findViewById(R.id.etdeprec1)).setText("");
			((EditText)MainActivity.this.findViewById(R.id.etdeprec2)).setText("");
			((EditText)MainActivity.this.findViewById(R.id.etdeprec3)).setText("");
		}

		@Override
		protected Void doInBackground(String... params) {
			try {
				LnC ws = new LnC(Double.parseDouble(params[0]), Integer.parseInt(params[1]));

				ws.executeWebService();

				if (Utils.isNullOrEmpty(ws.getResultatWS()))
					allOk = false;
				else
					allOk = ws.getResultatWS().equals("OK");
				//String result = ws.getResultatWS();
				
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// TODO Auto-generated method stub
			return null;
		}

	}

	
	public class DialogCat extends Dialog {

		public DialogCat(Context context) {
			super(context);
			// TODO Auto-generated constructor stub
		}
		
		@Override 
		public void onBackPressed() {
			this.cancel();
			MainActivity.this.refreshCats();
		}
	}
	

	
	public class DialogDesc extends Dialog {

		public DialogDesc(Context context) {
			super(context);
			// TODO Auto-generated constructor stub
		}
		
		@Override 
		public void onBackPressed() {
			this.cancel();
			MainActivity.this.refreshDescs();
		}
	}
	

    private static class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        private List<Desc> descs;
        
        public EfficientAdapter(Context context, List<Desc> descriptions) {
            // Cache the LayoutInflate to avoid asking for a new one each time.
            mInflater = LayoutInflater.from(context);
            
            descs = descriptions;    
        }

        /**
         * The number of items in the list is determined by the number of speeches
         * in our array.
         *
         * @see android.widget.ListAdapter#getCount()
         */
        public int getCount() {
            return descs.size();
        }

        /**
         * Since the data comes from an array, just returning the index is
         * sufficent to get at the data. If we were using a more complex data
         * structure, we would return whatever object represents one row in the
         * list.
         *
         * @see android.widget.ListAdapter#getItem(int)
         */
        public Object getItem(int position) {
            return descs.get(position);
        }

        /**
         * Use the array index as a unique id.
         *
         * @see android.widget.ListAdapter#getItemId(int)
         */
        public long getItemId(int position) {
            return descs.get(position).getDescID();
        }

        /**
         * Make a view to hold each row.
         *
         * @see android.widget.ListAdapter#getView(int, android.view.View,
         *      android.view.ViewGroup)
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            // A ViewHolder keeps references to children views to avoid unneccessary calls
            // to findViewById() on each row.
            ViewHolder holder;

            // When convertView is not null, we can reuse it directly, there is no need
            // to reinflate it. We only inflate a new View when the convertView supplied
            // by ListView is null.
            if (convertView == null) {
                convertView = mInflater.inflate(android.R.layout.simple_list_item_1, null);

                // Creates a ViewHolder and store references to the two children views
                // we want to bind data to.
                holder = new ViewHolder();
                holder.text = (TextView) convertView.findViewById(android.R.id.text1);

                convertView.setTag(holder);
            } else {
                // Get the ViewHolder back to get fast access to the TextView
                // and the ImageView.
                holder = (ViewHolder) convertView.getTag();
            }

            // Bind the data efficiently with the holder.
            holder.text.setText(descs.get(position).getCatName() + " - " + descs.get(position).getDescName());

            return convertView;
        }

        static class ViewHolder {
            TextView text;
        }
    }
}
